{
 "metadata": {
  "signature": "sha256:83e35d26f85d9a8df4a34e3ee6b5c3bf55e8acd4cbb606340fe88942aa2adccf"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "f2py and numpy\n",
      "======================================================================\n",
      "\n",
      "Wrapping C codes using f2py\n",
      "---------------------------\n",
      "\n",
      "While initially f2py was developed for wrapping Fortran codes for\n",
      "Python, it can be easily used for wrapping C codes as well. Signature\n",
      "files describing the interface to wrapped functions must be created\n",
      "manually and the functions and their arguments must have the attribute .\n",
      "See [f2py\n",
      "UsersGuide](http://docs.scipy.org/doc/numpy-dev/f2py/)\n",
      "for more information about the syntax of signature files.\n",
      "\n",
      "Here follows as simple C code"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "```\n",
      "/* File foo.c */\n",
      "void foo(int n, double *x, double *y) {\n",
      "  int i;\n",
      "  for (i=0;i<n;i++) {\n",
      "    y[i] = x[i] + i;\n",
      "  }\n",
      "}\n",
      "```"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "and the corresponding signature file"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "```\n",
      "! File m.pyf\n",
      "python module m\n",
      "interface\n",
      "  subroutine foo(n,x,y)\n",
      "    intent(c) foo                 ! foo is a C function\n",
      "    intent(c)                     ! all foo arguments are \n",
      "                                  ! considered as C based\n",
      "    integer intent(hide), depend(x) :: n=len(x)  ! n is the length\n",
      "                                                 ! of input array x\n",
      "    double precision intent(in) :: x(n)          ! x is input array \n",
      "                                                 ! (or  arbitrary sequence)\n",
      "    double precision intent(out) :: y(n)         ! y is output array, \n",
      "                                                 ! see code in foo.c\n",
      "  end subroutine foo\n",
      "end interface\n",
      "end python module m\n",
      "```"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "To build the wrapper, one can either create a setup.py script"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# File setup.py\n",
      "def configuration(parent_package='',top_path=None):\n",
      "    from numpy.distutils.misc_util import Configuration\n",
      "    config = Configuration('',parent_package,top_path)\n",
      "\n",
      "    config.add_extension('m',\n",
      "                         sources = ['m.pyf','foo.c'])\n",
      "    return config\n",
      "if __name__ == \"__main__\":\n",
      "    from numpy.distutils.core import setup\n",
      "    setup(**configuration(top_path='').todict())"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "and execute:"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "``python setup.py build_src build_ext --inplace``"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Or one can call f2py directly in command line to build the wrapper as\n",
      "follows:"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "``f2py m.pyf foo.c -c``"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "In both cases an extension module will be created to current directory\n",
      "that can be imported to python:"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "```\n",
      ">>> import m\n",
      ">>> print m.__doc__\n",
      "This module 'm' is auto-generated with f2py (version:2_2130).\n",
      "Functions:\n",
      "  y = foo(x)\n",
      ".\n",
      ">>> print m.foo.__doc__\n",
      "foo - Function signature:\n",
      "  y = foo(x)\n",
      "Required arguments:\n",
      "  x : input rank-1 array('d') with bounds (n)\n",
      "Return objects:\n",
      "  y : rank-1 array('d') with bounds (n)\n",
      "\n",
      ">>> print m.foo([1,2,3,4,5])    \n",
      "[ 1.  3.  5.  7.  9.]\n",
      ">>>\n",
      "```"
     ]
    }
   ],
   "metadata": {}
  }
 ]
}